package fr.xebia.monitoring.jdbc;

import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.DriverPropertyInfo;
import java.sql.SQLException;
import java.util.Properties;

import org.apache.log4j.Logger;

import fr.xebia.monitoring.Monitor;
import fr.xebia.monitoring.MonitorFactory;

public class MonitoredDriver implements Driver {
	
	private static final Logger logger = Logger.getLogger(MonitoredDriver.class);
	public static final String MONITORING_KEY = "MONITORING_KEY";
	public static final String MONITORING_JDBC_KEY = ":monitoring";

	private Driver innerDriver;
	private String monitoringKey;

	public MonitoredDriver() {
		super();
	}

	public boolean acceptsURL(String url) throws SQLException {
		if (url.startsWith("jdbc:monitoring:")) {
			return true;
		}
		return false;
	}

	private String getRealUrl(String url) throws SQLException {
		int indexOf = url.indexOf(MONITORING_JDBC_KEY);
		String realUrl = url.substring(0, indexOf) + url.substring(indexOf+MONITORING_JDBC_KEY.length());
		logger.debug("Real url: "+realUrl);
		return realUrl;
	}

	public Connection connect(String url, Properties info) throws SQLException {
		String realUrl = getRealUrl(url);
		innerDriver = DriverManager.getDriver(realUrl);
		if (info.getProperty(MONITORING_KEY) != null) {
			monitoringKey = "jdbc."+info.getProperty(MONITORING_KEY);
		} else {
			monitoringKey = "jdbc.["+url+"]";
		}
		Monitor monitor = MonitorFactory.start(monitoringKey, "driver.connect()");
		try {
			Connection connection = innerDriver.connect(realUrl, info);
			if (connection == null) {
				throw new SQLException("Can't get a connection to the real database");
			}
			return new MonitoredConnection(monitoringKey, connection);
		} finally {
			monitor.stop();
		}
	}

	public int getMajorVersion() {
		return innerDriver.getMajorVersion();
	}

	public int getMinorVersion() {
		return innerDriver.getMinorVersion();
	}

	public DriverPropertyInfo[] getPropertyInfo(String url, Properties info)
			throws SQLException {
		return innerDriver.getPropertyInfo(url, info);
	}

	public boolean jdbcCompliant() {
		return innerDriver.jdbcCompliant();
	}
}
